﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SimpleSocket.Samples.ChatCommon;

namespace SimpleSocket.Samples.ChatClient
{
    public partial class frmChatWindow : Form
    {
        public SimpleSocketClient Client = new SimpleSocketClient();
        private string username = "";
        private string host = "";

        public frmChatWindow()
        {
            InitializeComponent();
            Client.Connected += new ConnectionStateEventHandler(Client_Connected);
            Client.Disconnected += new ConnectionStateEventHandler(Client_Disconnected);
            Client.MessageReceived += new MessageReceivedEventHandler(Client_MessageReceived);
        }

        private void DoConnect()
        {
            // Make the dlg show up until they connect
            while(!Client.IsConnected)
            {
                frmConnect dlg = new frmConnect();
                dlg.ShowDialog(this);

                username = dlg.UserName;
                host = dlg.Host;

                this.Text = "Chat Room - " + username;

                Client.Connect(host, 5898);

                if (!Client.IsConnected)
                    MessageBox.Show("Could not connect");

            }
        }

        void Client_MessageReceived(object sender, ReceivedMessageEventArgs Args)
        {
            MessageType messageType = (MessageType)Args.Command;

            switch (messageType)
            {
                case MessageType.RequestUserName:
                    Args.SendResponce(username);
                    string[] users = Client.Request<string[]>(5, (int)MessageType.ListUsers);
                    Invoke((MethodInvoker)(() => { UpdateUserList(users); }));
                    break;
                case MessageType.ChatMessage:
                    ChatMessage msg = Args.DataAs<ChatMessage>();
                    Invoke((MethodInvoker)(() => { ChatMessageReceived(msg); }));
                    break;
                case MessageType.UserJoined:
                    Invoke((MethodInvoker)(() => { AddUser(Args.CommandText); }));
                    break;
                case MessageType.UserLeft:
                    Invoke((MethodInvoker)(() => { RemoveUser(Args.CommandText); }));
                    break;
                default:
                    break;
            }
        }

        void Client_Disconnected(object sender, EventArgs Args)
        {
            Invoke((MethodInvoker)(() => { DoConnect(); }));
        }

        void Client_Connected(object sender, EventArgs Args)
        {
            
        }

        private void RemoveUser(string userName)
        {
            lstUsers.Items.Remove(userName);
        }

        private void AddUser(string userName)
        {
            lstUsers.Items.Add(userName);
        }

        private void ChatMessageReceived(ChatMessage msg)
        {
            txtChat.AppendText(string.Format("{0}: {1}\r\n", msg.FromUser, msg.Message));
        }

        private void UpdateUserList(string[] users)
        {
            lstUsers.Items.Clear();
            foreach (string u in users)
                lstUsers.Items.Add(u);
        }

        private void frmChatWindow_Load(object sender, EventArgs e)
        {
            DoConnect();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (Client.IsConnected && txtChatSend.Text != "")
            {
                ChatMessage msg = new ChatMessage();
                msg.FromUser = username;
                msg.MessageDate = DateTime.Now;
                msg.Message = txtChatSend.Text;

                Client.Send((int)MessageType.ChatMessage, msg);

                txtChatSend.Text = "";
            }
        }

        private void txtChatSend_KeyDown(object sender, KeyEventArgs e)
        {
            if(e.KeyCode == Keys.Enter || e.KeyCode == Keys.Return)
                btnSend_Click(this, EventArgs.Empty);
        }
    }
}
